package org.parademo.dao;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.parademo.exception.CorruptDatabaseException;
import org.parademo.model.TopicEntity;
import org.parademo.web.model.TopicView;

import java.util.List;

public class TopicDao extends GenericDao<TopicEntity> {

    public TopicEntity retrieve(Long id) {
        return (TopicEntity) getCurrentSession().get(TopicEntity.class, id);
    }

    //Remove of the two create methods.
    public void create(TopicEntity entityToCreate) {

        getCurrentSession().save(entityToCreate);
    }

    public TopicDao(SessionFactory sessionFactory) {
        super(sessionFactory);
    }

     public TopicEntity getTopicById(long topicId) {
        return (TopicEntity) getCurrentSession().get(TopicEntity.class, topicId);
    }

    public TopicEntity getTopicByName(String name) {
        Query query = getCurrentSession().createQuery(
                "from\n" +
                "    TopicEntity u\n" +
                "where\n" +
                "    u.name = :name\n"
        );
        query.setString("name", name);

        @SuppressWarnings("unchecked")
        List<TopicEntity> topicList = query.list();

        int topicCount = topicList.size();
        if (topicCount == 0) {
            return null;
        }

        if (topicCount > 1) {
            throw new CorruptDatabaseException(
                    "Found " + topicCount + " topics with the same name [" + name + "].\n" +
                    "The database should have a unique constraint for the name to prevent this from happening."
            );
        }

        return topicList.get(0);
    }

     public void update(TopicEntity entityToUpdate) {

         getCurrentSession().merge(entityToUpdate);
     }

    public void delete(TopicEntity entityToDelete) {
        throw new UnsupportedOperationException("unimplemented"); // todo: implement this
    }

    @SuppressWarnings("unchecked")
    public List<TopicEntity> getTopics() {
        Query query = getCurrentSession().createQuery(
                "from TopicEntity"
        );

        return query.list();
    }

    @SuppressWarnings("unchecked")
    public long createTopic(TopicView topicView){
        Session session = getCurrentSession();

        TopicEntity topicEntity=copyTopicViewInTopicEntity(topicView);
        Long topicId = (Long) session.save(topicEntity);
        topicEntity.setId(topicId);
        return topicId;
    }

    private TopicEntity copyTopicViewInTopicEntity(TopicView topicView){
        TopicEntity topicEntity=new TopicEntity();
        topicEntity.setDescription(topicView.getDescription());
        topicEntity.setName(topicView.getName());
        return topicEntity;
    }

}
